#include "GameLogic.h"
#include "EntityManager.h"
#include "Resources.h"
#include "InputHandler.h"

#define ENEMY_DELAY 15.f;
#define SCORE_FOR_KILL 10;

GameLogic::GameLogic(void)
{
	EntityCount.SetPosition(700,20);
	EntityCount.SetColor(sf::Color::Red);
	EntityCount.SetCharacterSize(18);

	PlayerScore.SetPosition(10,10);
	PlayerScore.SetColor(sf::Color::Black);
	PlayerScore.SetCharacterSize(32);
	PlayerScore.SetString("Score: 0");

	FrameTime.SetPosition(700,40);
	FrameTime.SetColor(sf::Color::Red);
	FrameTime.SetCharacterSize(18);

	HealthBar.SetTexture(*Resources::Instance()->RequestImage("healthpack"));
	HealthBar.SetScale(0.5,0.5);
	HealthBar.SetOrigin(32,32);
	Score = 0;
	NextFrameTime = 0.f;
}


GameLogic::~GameLogic(void)
{
}

void GameLogic::Initialize()
{
	Player = EntityManager::Instance()->CreateEntity("ent_player");
	ViewCam = EntityManager::Instance()->CreateEntity("camera");
	EntityManager::Instance()->CreateEntity("ent_enemy");
	EntityManager::Instance()->CreateEntity("ent_world");

	for (int i=0; i < 300; i++)
	{
		EntityManager::Instance()->CreateEntity("ent_crate");
	}
	for (int i=0; i < 10; i++)
	{
		EntityManager::Instance()->CreateEntity("ent_wall");
	}
	NextEnemy = ENEMY_DELAY;
}

void GameLogic::OnKeyPressed(sf::Keyboard::Key Key, sf::RenderWindow &render)
{
	if (Key == sf::Keyboard::Space)
	{
		BaseEntity* Crate = EntityManager::Instance()->CreateEntity("ent_crate");
		Crate->SetPos(InputHandler::GetMousePosWorld(render));
	}
}

void GameLogic::OnCollision(BaseEntity* ent1, BaseEntity* ent2, CollisionData* Info)
{
}

void GameLogic::Tick()
{
	if (GameGlobals::Instance()->CurTime > NextFrameTime)
	{
		char Buffer[32];
		sprintf_s(Buffer, "Frametime %f", GameGlobals::Instance()->FrameTime);
		FrameTime.SetString(Buffer);
		NextFrameTime = GameGlobals::Instance()->CurTime + 1.f;
	}
	if (!Player->GetAlive())
	{
		std::vector<BaseEntity*>enem;
		EntityManager::Instance()->FindByClass("ent_enemy", enem);
		
		std::vector<BaseEntity*>::iterator i = enem.begin();
		while (i != enem.end())
		{
			(*i)->Delete();
			i++;
		}
		EntityManager::Instance()->FindByClass("ent_healthpack", enem);
		i = enem.begin();
		while (i != enem.end())
		{
			(*i)->Delete();
			i++;
		}
		EntityManager::Instance()->FindByClass("ent_decal", enem);
		i = enem.begin();
		while (i != enem.end())
		{
			(*i)->Delete();
			i++;
		}
		Score = 0;
		std::cout << "GAME OVER\n";		
		Player->SetPos(0,0);
		Player->SetAngle(0);
		Player->SetHealth(Player->GetMaxHealth());
		Player->SetAlive(true);
	}
	if (NextEnemy < GameGlobals::Instance()->CurTime)
	{
		EntityManager::Instance()->CreateEntity("ent_enemy");
		NextEnemy = GameGlobals::Instance()->CurTime + ENEMY_DELAY;
	}
	sf::Vector2f NewPos = ViewCam->GetPos();
	float Speed = Util::Distance(NewPos, Player->GetPos()) / 50.f;
	NewPos.x = Util::Approach(NewPos.x, Player->GetPos().x, Speed);
	NewPos.y = Util::Approach(NewPos.y, Player->GetPos().y, Speed);
	ViewCam->SetPos(NewPos);
}

void GameLogic::DrawHUD(sf::RenderWindow *render)
{
	render->Draw(EntityCount);
	render->Draw(FrameTime);
	for (int i=0; i < Player->GetMaxHealth(); i+=10)
	{
		if (i <= Player->GetHealth())
		{
			HealthBar.SetPosition(30 + (i * 3.2f), 740);
			if (i+10 > Player->GetHealth())
			{
				sf::Color col = sf::Color(255,255,255, (Player->GetHealth() - i) / 10.f * 255.f);
				HealthBar.SetColor(col);
			}
			else
				HealthBar.SetColor(sf::Color::White);
		}
		else
		{
			sf::Color col = sf::Color(255,255,255, 30.f);
			HealthBar.SetColor(col);
			HealthBar.SetPosition(30 + (i * 3.2f), 740);
		}
		render->Draw(HealthBar);
	}
	render->Draw(PlayerScore);
}

void GameLogic::OnEntityCreated(BaseEntity* ent)
{
	char Buffer[32];
	sprintf_s(Buffer, "Entity Count: %i", GameGlobals::Instance()->EntityCount);
	EntityCount.SetString(Buffer);
}

void GameLogic::OnEntityDestroyed(BaseEntity* ent)
{
	char Buffer[32];
	sprintf_s(Buffer, "Entity Count: %i", GameGlobals::Instance()->EntityCount);
	EntityCount.SetString(Buffer);

	if (ent->GetClassName() == std::string("ent_enemy") && ent->GetHealth() <= 0) //it was killed
	{
		Score = Score + SCORE_FOR_KILL;
	}
	sprintf_s(Buffer, "Score: %i", Score);
	PlayerScore.SetString(Buffer);
}
